var fs = require('fs'), 
        path = require('path');

var Schedule = function (nameEntity) {
    this.nameEntity = nameEntity;
}
/**
 * Sert à vérifier que l'extension est bien au format CSV
 * 
 * @param file fichier à vérifier
 *
 * @return un booléen (true si le fichier est un CSV, false si non)
 */
function isCsvFile (file) {
        return file.split(".").pop() == "csv" ? true : false;
}

/**
 * Sert à obtenir tout les fichiers d'un répertoire
 * 
 * @see isCsvFile
 *
 * @param path chemin du répertoire
 *
 * @return filesCsv tout les noms des fichiers du répertoire
 */
function getFilesCsv (path) {
        var filesDir = fs.readdirSync(path);
        var filesCsv = [];

        for (var i=0, j=0; i<filesDir.length; i++) {
                if (  isCsvFile(filesDir[i]) ) { // Si le fichier est un CSV
                        filesCsv[j] = filesDir[i];
                        j++;
                } 
        }

        return filesCsv;
}

/**
 * Créer un planning en tableau à 2 dimensions
 *
 * @return scheduleToArray planning sous un tableau à 2 dimensions
 */
function newScheduleToArray () {
        var scheduleToArray = [];
        scheduleToArray[0] = ["lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"];

        for (var i=1; i<49; i++) {
                scheduleToArray[i] = new Array();
                for (var j=0; j<7; j++) {
                        scheduleToArray[i].push("vide");
                }
        }

        return scheduleToArray;
}

/**
 * Convertit un fichier CSV en tableau
 *
 * @param fileCsv fichier CSV à convertir en tableau
 *
 * @return csvFileArray le tableau par rapport au données du fichier CSV
 */
function csvToArray (fileCsv) {
        var i = 0, csvFileArray = [];
                
        fileCsv.split('\n').forEach(function(line) {
                csvFileArray[i] = line.split(';')
                i++;
        });

        return csvFileArray;
}

/**
 * Récupère le(s) nom(s) de(s) entité(s) d'un évènement
 *
 * @param event un évènement d'un planning csv 
 *
 * @return une chaine de caractère de(s) entité(s) liée(s)
 */
function getNameEntityEvent (event) {
    return event.substring(event.indexOf("(")+1, event.indexOf(")"));    
}

/**
 * Récupère l'évènement de(s) entité(s)
 *
 * @param event un évènement d'un planning csv 
 *
 * @return une chaine de caractère de(s) entité(s) liée(s)
 */
function getEntitysEvent (event) {
    return event.substring(event.indexOf("(")+1, event.lastIndexOf(")")+1);    
}

/**
 * Vérifie que l'entité d'un évènement correspond à celui qu'on souhaite générer le planning
 *
 * @param entityFocus nom de l'entité que l'on souhaite en générer le planning
 * @param event un évènement d'un planning csv 
 *
 * @return un booléen pour signaler si l'évènement nous intéresse pour générer le planning
 */
function isFocusEntity (entityFocus, event) {
        var entityOfEvent = getNameEntityEvent(event);

        return entityOfEvent == entityFocus ? true:false;
}

/**
 * Mettre à jour le planning qui sera généré en fonction de l'évènement 
 *
 * @param fileArray correspond à un planning qu'on analyse pour savoir si des évènements sont 
 * à extraire pour la génération du planning
 * @param entityScheduleArray correspond au planning qui va être généré
 * @param fileName correspond au nom de l'entité dont on analyse le planning
 * @param entityName correspond au nom de l'entité que l'on souhaite générer le planning
 */
function buildEntityScheduleArray (fileArray, entityScheduleArray, fileName, entityName, path) {
        for (var i=0; i<49; i++) {
                for (var j=0; j<7; j++) {
                        if (fileArray[i][j] != "vide" && isFocusEntity(entityName, fileArray[i][j])) {
                            if (entityScheduleArray[i][j] != "vide") { // Gestion des conflits
                                entityScheduleArray[i][j] = entityScheduleArray[i][j].replace(
                                    getEntitysEvent(entityScheduleArray[i][j]),
                                    getEntitysEvent (entityScheduleArray[i][j])+", "+fileArray[i][j].replace(entityName, fileName)
                                );
                            } else {
                                 entityScheduleArray[i][j] = fileArray[i][j].replace(entityName, fileName);
                            }
                        }       
                }
        }
}

/**
 * Convertir un CSV sous un format tableau en une chaine de caractère
 *
 * @param array correspond au fichier CSV sous un format tableau 
 *
 * @return str retourne le tableau convertit
 */
function arrayToCsvToString(array) {
        var str = "";
        for (var i=0; i<49; i++) {
            str += array[i].join(";");
            if ( i != 48)
                str += "\n";
        }
        return str;
}

/**
 * Générer le planning d'une entité donné en console
 *
 * @param entityName nom de l'entité que l'on souhaite en générer le planning
 * @param fileName nom de l'entité dont on analyse son planning
 * @param path chemin du fichier à analyser
 */
Schedule.prototype.generateScheduleToFileCsv = function (entityName, fileName, path){

        entityScheduleArray = newScheduleToArray();

        fs.readFile(path, 'utf8', function (err, fileCsv) {
                if (err) {
                        return console.log(err);
                }
                
                var fileArray = csvToArray(fileCsv);

                buildEntityScheduleArray(fileArray, entityScheduleArray, fileName, entityName, path);           

                var entityScheduleStr = arrayToCsvToString(entityScheduleArray);
                fs.writeFile(entityName+".csv", entityScheduleStr, function (err) {
                        if (err) {
                                return console.log(err);
                        }
                        
                });
        }); 
};

/**
 * Générer le planning d'une entité donné en console :
 * Il semble évident que les fichiers CSV du répertoire soit correct, 
 * puisqu'on importe pas des fichiers dans notre système incorrect
 *
 * @param nom de l'entité que l'on souhaite en générer le planning
 * @param chemin du répertoire dont on souhaite récupérer les fichier CSV afin de les analyser
 *
 */
Schedule.prototype.buildEntityScheduleToCsv = function  (pathDir) {
        if ( pathDir == null ) { // Considérer comme répertoire courant
                pathDir = ".";
        }

        var filesCsv = getFilesCsv(pathDir);
        
        var fileName, pathFile;
        
        for (var i in filesCsv) {
                (fileName = filesCsv[i].split(".")).pop(); // Récupère le nom du fichier
                pathFile = pathDir+"/"+fileName+".csv";
                this.generateScheduleToFileCsv(this.nameEntity, fileName, pathFile);
        }
        
};


//-------------------MAIN---------------------//
//---------------Test Spec.4-----------------//
var schedule = new Schedule(process.argv[2]);

schedule.buildEntityScheduleToCsv(process.argv[3]);


//-------------------------------------------//